# https://jumpserver.9981.team/api/docs
# https://docs.jumpserver.org/zh/master/dev/rest_api/
#此脚本单纯只是做资产导入，通过读取csv 文件做导入：
# csv 文件字段说明：
# 例如： k8s-node1,192.168.111.81,Linux,True,22,ssh,common,node100
# 第一个：资产唯一名字
# 第二个：资产ip
# 第三个：资产系统平台
# 第四个：资产激活状态，一般都默认为True
# 第五个：资产连接端口
# 第六个：资产连接协议
# 第七个：系统用户(此处非必须)
# 第八个：资产节点


import requests
import json
import sys
import csv

JmsToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
JmsBaseApi = "https://xxxxx.com"


# 此类做token 是否可用判断以及涉及post方法的处理
# get 获取jms状态判断
# post 对jms进行改动操纵
class HTTP(object):
    def __init__(self, *args):
        server = None
        token = None
        token_status = False

    # token可用性判断
    @classmethod
    def check_token(cls, server, token):
        uri = "/api/v1/users/users"
        url = server + uri
        print(url)
        headers = {
            'Authorization': 'token ' + token, 
            # 'X-JMS-ORG': '00000000-0000-0000-0000-000000000002',
            'content-type': "application/json"
        }
        res = requests.get(url, headers=headers)
        if res.status_code == 200:
            cls.server = server
            cls.token = token
            cls.token_status = True
            # print(res.text)
            print("token 正常")

        else:
            print("token 不可用")
            # print(res.text)
            sys.exit()
        print(cls.server, cls.token, cls.token_status)

    # get方法获取jms信息
    @classmethod
    def get(cls, uri, data=None, *args, **kwargs):
        if cls.token_status == True:
            url = cls.server + uri
            headers = {
                'Authorization': 'token ' + cls.token, 
                # 'X-JMS-ORG': '00000000-0000-0000-0000-000000000002',
                'content-type': "application/json"
            }
            res = requests.get(url, headers=headers, params=data)
        else:
            print("token 不可用")
            sys.exit()
        return res

    # post方法获取jms信息或操作jms
    @classmethod
    def post(cls, uri, data=None, *args, **kwargs):
        if cls.token_status == True:
            url = cls.server + uri
            headers = {
                'Authorization': 'token ' + cls.token, 
                # 'X-JMS-ORG': '00000000-0000-0000-0000-000000000002',
                'content-type': "application/json"
            }
            data = json.dumps(data)
            print(data)
            res = requests.post(url, headers=headers, data=data)
            print("post 结果", res.status_code, res.json())
        else:
            print("token 不可用")
            sys.exit()
        return res

# 资产列表节点管理
# 判断节点是否存在
# 节点不存在则创建
class NODE(object):
    def __init__(self, *args):
        self.id = None
        # self.node_full_name = None
        self.name = None
    
    # 判断资产节点是否存在，存在则获取资产节点id，若不存在则新建资产节点并获取id
    # 目前无法post full_value 控制只能post value zz
    def exist(self, name):
        uri = "/api/v1/assets/nodes/"
        self.name = name
        # self.node_full_name = full_name
        # self.name = self.node_full_name.split('/')[-1]
        # if self.node_full_name == self.name:
        #     print("输入资产节点名字不合规")
        #     sys.exit()

        data = { "value": self.name
        }
        res = HTTP.get(uri, data)
        res_data = res.json()
        if res.status_code == 200 and res_data:
            print("资产节点 {} 已经存在".format(self.name))
            self.id = res_data[0].get('id')
            print(res_data)
            print(res.status_code, type(res_data))
        else:
            self.create()
            
    def create(self):
        print("创建资产节点 {}".format(self.name))
        data = { 
            "value": self.name
        }
        uri = "/api/v1/assets/nodes/"
        res = HTTP.post(uri, data)
        print(res.status_code, res.json())
        self.id = res.json().get('id')  

# 判断资产是否存在以及创建资产
class ASSET(object):
    def __init__(self, *args):
        self.id           = None
        self.name         = None
        self.ip           = None
        self.platform     = None
        self.protocols    = None
        self.node_name    = None
        self.active       = None
        self.port         = None
        self.protocol     = "ssh"
        # self.admin_user   = AdminUser()
        self.node         = NODE()

    # 判断资产是否已经存在
    def exist(self, assetsinfo):
        self.name = assetsinfo[0] # 资产唯一名字
        self.ip = assetsinfo[1]   # 资产ip
        self.platform = assetsinfo[2] # 资产系统
        self.protocol = assetsinfo[5] # 资产链接协议
        self.port = assetsinfo[4]   # 资产连接端口
        self.node_name = assetsinfo[7]  # 资产节点名字
        self.active = assetsinfo[3]  # 资产是否激活默认都是True
        # self.protocols = ['ssh/22' if self.platform == 'Linux' else  'rdp/3389']

        uri = "/api/v1/assets/assets/"
        data = {
            "hostname": self.name
        }
        res = HTTP.get(uri, data)
        res_data = res.json()
        if res.status_code in [200, 201] and res_data:
            print(res_data)
            print('资产 {} 已存在'.format(self.name))
            self.id = res_data[0].get('id')
            print(self.id)
        else:
            print("即将新建")
            self.create()

    # 当资产不存在时创建资产
    def create(self):
        print("新建资产 {} ".format(self.name))
        self.node.exist(self.node_name)

        uri = "/api/v1/assets/assets/"
        data = {
            "hostname": self.name,
            "ip": self.ip,
            "platform": self.platform,
            # "protocols": self.protocols,
            "port": self.port,
            "protocol": self.protocol,
            "nodes": [self.node.id],
            "is_active": True
        }
        res = HTTP.post(uri, data)
        self.id = res.json().get('id')
        print(self.id)


HTTP.check_token(JmsBaseApi, JmsToken)
print(HTTP.token_status, HTTP.token, HTTP.server)

# 后面有空再改用多线程
with open('hostinfo.csv', 'r') as f:
    reader = csv.reader(f)
    print(type(reader))
    assert_change = ASSET()
    for row in reader:
        assert_change.exist(row)
    

